/*
本文件名：core.cpp
它是基于C++的《观天道》游戏的引擎。
在Linux环境下执行：
g++ -std=c++17 -pthread -Wall -O2 core.cpp && ./a.out 
即可使用。


游戏设计文档 (Game Design Document - GDD)
1. 引言

在数字世界中，我们渴望的不仅仅是消费内容，更是创造内容、甚至创造一个“活生生”的世界。本项目旨在打造一个超越传统游戏范畴的“可编程数字生命世界”，玩家不再仅仅是消费者，更是这个世界规则的定义者、生态的塑造者。通过“道机”驱动下的代码博弈和虚拟生命演进，我们相信这将为玩家提供一个充满创造、挑战和无限可能性的独特体验，开启数字互动娱乐的新篇章。本游戏主要面向全球（尤其是英语区）对编程、策略和创造性玩法感兴趣的硬核玩家。
2. 核心理念

    数据即指令： 存储在特定内存地址的字节序列，在被“道机”PC指针访问时，会被解释并执行为指令，从而改变系统状态、其他内存内容，甚至图像显示。
    HTTP即接口： 所有与虚拟计算机的交互都通过标准的HTTP请求完成，极大降低了用户参与的门槛和开发复杂度。玩家的HTTP请求会被系统排队，并由后台的“道机”核心引擎进行统一处理，从而确保世界状态更新的原子性和一致性。
    世界即程序： 整个公共区内存空间构成了一个宏大的、持续运行的“程序”。玩家的每一次写入，都是对这个全球程序的干预，共同塑造其演变。
    算法即战争： 玩家之间的竞争不再是数值或角色对抗，而是编写、优化、部署和攻防指令的智能博弈。

3. 内存架构概览

游戏世界的核心是一个庞大的虚拟内存空间，被划分为三个主要区域，并通过独特的“保险箱”可视化界面呈现给玩家。

    系统区 (SYS Segment - 1MB)：
        用途：预留。用于存储系统核心指令、全局配置、系统内部使用的少量关键元数据（例如全局时间戳、特殊系统标志等）、公共区访问权限表等。
        权限：除游戏运营方（即“超级用户”）外，对玩家可读不可写。
        特性：无访问频率限制（但系统会防止滥用）。
    公共区 (PUB Segment - 1MB，即 1024x1024B)：
        用途：开放且可视化。一个巨大的共享内存空间，其数据被实时渲染为图像。此区域的数据即是指令，由在此区域运行的“道机”持续执行。
        权限：全民可读。写入权限通过租赁获得。
        可视化：整个1MB内存抽象为1024x1024像素的网格，每个字节的数据映射为颜色、亮度或图案，形成动态图像。
    私有区 (PRV Segment - 每个用户初始1KB免费，可内购扩容)：
        用途：私密。每个用户独立的存储空间，可用于指令练习、个人数据存储或预先孵化复杂的程序。
        权限：由用户通过管理密码、读密码、写密码进行控制。
        特性：是一个巨大的虚拟地址空间。每个玩家初始1KB免费配额，可以购买更多。理论上无上限，但实际上每人2^32B（约4GB）应该足以满足绝大多数复杂程序的需求。

3.1 内存可视化：保险箱海洋

    本质：所有内存地址被抽象为一排排的“保险箱”。
    单字节设计：每个“保险箱”存储一个字节的数据，强调其纯粹的数学美和底层控制。
    箱子身份：当名字是数字时，它作为“地址”使用；当名字是字符串时，可作为“标签”或“变量名”提供更友好的访问方式，例如 getByte("my_variable") 而不是 getByte(12345)。
    读写权限：系统区由游戏运营方控制。公共区全民可读，写入权限通过租赁获得。私有区由用户通过管理密码、读密码、写密码进行控制。
    遨游界面：提供一个直观的内存浏览界面，可直接输入地址定位，并通过滚轮浏览相邻区域，支持目录导航（系统段、公共段、私有段及其内部段落）。当其他玩家在遨游时，私有区内容将以“???”形式展示，但会明确标注该区域的“地主”（用户ID或昵称），以促进交易和互动。

4. 核心玩法与系统设计
4.1 HTTP计算机核心

    数据结构：内存被视为一个巨大的字节数组，每个字节有唯一的地址。
    基础指令集 (示例)：
        MOV [addr_dest] [addr_src/value]：移动数据。
        ADD [addr_dest] [addr_src/value]：加法。
        SUB [addr_dest] [addr_src/value]：减法。
        JMP [addr]：无条件跳转PC指针。
        JEQ [addr] [val1] [val2]：条件跳转（如果相等）。
        SET_COLOR [addr_x] [addr_y] [color_code]：公共区专用，将指定坐标像素设置为颜色。
        NOP：空操作。
    进阶指令：通过学习或内购获取，用于构建复杂逻辑（条件执行、内存扫描、权限检查、随机数生成、延迟执行等）。
    HTTP API (示例)：
        GET /pub_mem?addr={address}&len={length}: 从公共区读取字节数据（字节流或编码字符串）。
        POST /pub_mem: 向公共区写入字节数据，需携带用户权限凭证 (token)、起始地址 (addr) 和要写入的数据 (data)。
        POST /lease_mem: 租赁公共区指定范围的写入权限（存储资源），需携带起始地址 (addr)、长度 (len)、时长 (duration_hours) 和用户凭证 (token)。返回租赁ID，到期时间等。
        POST /start_tao: 在用户拥有或租赁的内存段中启动一个“道机”（计算资源），需携带关联的内存租赁ID (lease_id)、用户凭证 (token) 和可选的起始执行地址 (start_addr)。返回道机ID，状态等。道机启动后，其运行将持续消耗用户账户的coin。
        GET /pub_image: 获取公共区当前渲染的图片（例如Base64编码或直接图片URL）。
        GET /private_mem?addr={address}&len={length}: 从私有区读取字节数据。
        PUT /private_mem: 向用户私有区指定地址写入字节数据，需携带用户凭证 (token)、起始地址 (addr) 和数据 (data)。
        POST /set_private_password: 设置私有区管理、读、写密码，需携带用户凭证 (token)、段ID (segment_id) 和新密码。
        GET /public/my_leases: 查询当前用户拥有的公共区租赁权限和启动的道机。

4.2 “道机”运行机制

    多个“道机”：游戏中不再是单一全局“天道”，而是玩家可以租赁并在其代码段中启动的多个独立“道机”。每个道机拥有独立的PC指针和执行状态。
    服务器内部运行：道机是游戏后台服务器内部运行的模拟计算单元，将其理解为游戏系统内的一个个‘虚拟处理器’或‘执行线程’。它们在玩家租赁的内存段中，在游戏服务器的CPU资源上执行玩家上传的指令。这个执行过程是完全在游戏服务器的内部完成的，与HTTP通信无关。
    HTTP/API用于玩家与游戏系统交互：HTTP（或API接口）的作用是玩家作为用户，向游戏系统发送‘指令’或‘请求’（例如：启动道机、上传代码、查询状态），而不是道机‘执行指令’的机制。道机一旦被玩家指令启动，就会在游戏服务器内部独立运行，其持续运行仅受用户账户coin和公共区内存租赁有效期的限制。
    coin系统：每个用户有一个“coin”上限。每次对 Data Bank 进行原子操作（玩家通过HTTP API发起的读一个字节、写一个字节、查询权限、分配内存等）消耗coin。具体设定为：读操作耗费1coin，写操作耗费2coin。由玩家设计并启动的道机，每运行1个指令，消耗1coin。coin会随着时间缓慢恢复（例如每秒恢复 10 coin，或每分钟恢复 600 coin）。当道机在执行指令时，如果其所属用户账户的coin不足，道机将自动暂停运行，直到账户恢复足够的coin。
    核心：道机是世界的“心跳”和“驱动力”。玩家通过写入指令并启动道机，改变的是道机未来将要执行的程序流，从而影响整个世界的运行和视觉表现。

4.3 公共区：算法战场与虚拟生命引擎

    全民可读，可视化呈现：整个1MB内存被抽象为1024x1024像素的网格。每个字节的数据可以映射为颜色、亮度或特定图案，形成一个动态变化的图像。玩家的代码效果直接在图像上展现。
    格子的“写入权限”与“计算资源”租赁：
        玩家使用游戏币租赁公共区特定内存格子的写入权限（存储资源）。租赁时长决定了玩家可以在该区域部署指令的时间。租赁的不是格子的所有权，而是在特定时间段内，允许用户在此区域内写入指令或数据的权利。租赁期满后，该区域的写入权限将解除，其他玩家可以重新租赁。
        玩家还可以在自己拥有或租赁的内存段中，向Bank租赁计算资源，即启动一个“道机”。道机启动后，其持续运行将消耗玩家账户的coin。
    “算法战争”的核心玩法：
        目标：玩家通过编写程序（指令序列），在公共区争夺代码领地、显示自己的视觉标识、部署功能性程序，或破坏对手的程序。
        攻防策略：
            程序部署：租赁一块区域，写入自己的程序，让“道机”执行时实现特定功能。
            领地争夺：编写能够自我复制、自我扩散的程序（算法病毒），尝试在公共区占据更多内存空间，或者覆盖其他玩家的指令。
            防御系统：编写能够检测自身指令是否被篡改的程序，并在发现攻击时尝试修复或反击。

             **资源竞争**：通过巧妙的指令设计，让“道机”在公共区更高效地执行自己的代码，从而获得优势，从而节省coin消耗。

            协作与联盟：多个玩家可以租赁相邻区域，共同部署一个大型程序，形成联盟。
        视觉反馈：成功部署的程序会按照玩家的意图改变公共区的图像，例如显示玩家的标志、动态动画，或清除其他玩家的“涂鸦”。失败或被入侵的区域可能显示为损坏、乱码。
    虚拟生命的诞生：鼓励玩家编写具有复杂逻辑的指令序列。这些指令可能通过自我修改、对周围环境（其他内存数据）的感知和反应、甚至自我复制、自我修复，逐渐形成具有类似生命特征的算法实体。它们可能在公共区争夺资源、进化、合作或相互攻击，形成一个意想不到的数字生态系统。

4.4 私有区：指令训练与程序孵化

    个人沙盒：用户可以在此区域自由编写、测试和调试指令，不会影响公共区。
    调试工具：提供强大的调试器和可视化工具，帮助玩家理解指令运行机制。
    程序孵化：玩家在私有区精心设计和优化他们的“算法武器”或“虚拟生命”程序，待成熟后再部署到公共区。
    任务系统：提供编程挑战和教程，引导玩家掌握指令集、编程逻辑和高级算法技巧。
    内购：玩家可以通过游戏内购扩充私有区的存储空间，以便开发更复杂的程序。

5. 示例：玩家想在公共区显示“机器猫头像”

这个场景完美体现了游戏的深度和策略性：

    方案一：直接程序化绘制（成本高，但直接）
        策略：玩家租赁覆盖机器猫头像所需的所有内存格子（例如，一个100x100像素的区域，就需要租赁100x100个字节的写入权限）。
        部署：然后，玩家通过HTTP POST /pub_mem 请求，在这些格子中写入一系列 SET_COLOR [x] [y] [color] 指令，以及必要的坐标和颜色数据。这些指令将直接定义每个像素的颜色。
        执行：当“道机”PC指针扫描到这些指令时，它会逐条执行这些 SET_COLOR 指令，将机器猫的头像在图像上逐像素地绘制出来，并持续消耗玩家账户的coin。
        特点：简单直接，但对租赁面积和coin消耗要求高。一旦租赁到期或被其他玩家的指令覆盖（如果指令设计允许），图像就会消失或被破坏。这考验玩家的资源管理能力和对图像数据的理解。

    方案二：高效算法生成与维护（技术性高，但节省资源且更具韧性）
        策略：玩家在私有区精心编写一个程序。这个程序的核心逻辑是：当它被“道机”执行时，它能高效地计算并写入机器猫头像的像素数据（通过循环、数学函数、压缩算法等）。
        部署：玩家只需租赁一小块公共区内存来存放这个程序代码本身，并在此区域启动一个道机。这个道机程序会利用其在租赁期内的持续运行能力，通过指令不断修改或绘制机器猫头像所需的像素数据，每次指令执行都消耗coin。
        进阶：这个程序甚至可以包含自修复逻辑。例如，它能检测机器猫头像的某个部分是否被其他玩家的指令篡改，并在下次“道机”执行时自动修复它。或者通过巧妙的指令，让程序将像素数据写入其他未被租赁的、或被设计为漏洞的公共区内存。
        特点：租赁成本相对较低，但对玩家的编程和算法设计能力要求极高。这个程序能够动态地维持图像存在，甚至抵抗攻击，体现了真正的“算法战争”精髓，同时对coin的优化使用至关重要。

6. 游戏卖点

    极高的自由度与创造性：玩家是虚拟世界的程序员和造物主，从像素级控制到复杂的算法生命，一切皆由代码实现。
    独一无二的深度策略性：结合编程、博弈论、资源管理，玩家需设计巧妙的算法来攻防、占领和维护。
    实时、动态的视觉反馈：抽象的代码逻辑被直观地渲染成动态图像，玩家能即时看到其代码对世界产生的影响。
    涌现式玩法与未知：世界由玩家的指令共同塑造，没有预设结局，可能诞生出意想不到的复杂生态和“虚拟智能”。
    低门槛高上限：基于HTTP接口，易于上手；但其内在的编程和策略深度能吸引硬核玩家长期投入。
    神秘感与沉浸感：借鉴“西洋镜”的理念，营造一个煞有介事的“观天道”世界，让玩家体验一种未知的探索乐趣，不买则无从知晓。

7. 商业模式

    公共区写入权限租赁：核心收入来源。玩家需支付游戏币租赁公共区内存的写入权限，按时长和面积收费。
    “道机”启动与coin销售：
        玩家需支付一次性游戏币来启动一个道机，使其开始在租赁的内存段中执行指令。
        道机运行将持续消耗用户账户的coin。玩家可以通过充值游戏币购买额外的coin。
    私有区存储扩容：内购，玩家需要更大的空间来开发和测试复杂的程序。
    特殊指令/高级工具包：
        出售一些更高效、更强大的基础指令模块或库函数。
        提供高级调试器、性能分析器、代码模板等辅助工具。
    游戏币销售：玩家可以通过充值获得游戏币，用于租赁权限、启动道机、购买coin和购买工具。
    外观定制：自定义HTTP客户端外观或私有区界面主题。
    指令/算法交易市场（未来发展）：玩家可以编写和出售自己设计的指令模块、算法程序或“虚拟生命模板”。

8. 交易机制

    赛博土地置换：玩家可以用自己租赁的一个连续公共区内存段交换别人租赁的一个连续段。交换的目的是使自己的地址连续显得阔绰，或使别人的地址不连续，迫使别人用其他连续的地址换回。

9. 游戏收费

    游戏本体购买：玩家购买游戏后第一次打开进入游戏即完成注册，用户名是Steam ID，密码是系统随机分配的sha256。这个sha256是用户初始512B私有区的管理密码。游戏费用我们会常常调整。
    额外私有地址购买：额外私有地址的定价应设置为远超我们运营成本的价格。

10. 命名约定

    游戏名称：Data Bank: The Tao Computer (中文名：观天道)
    计算机单元：道机 (Tao Machine)


*/

#include <iostream>
#include <string>
#include <vector>
#include <memory>
#include <mutex>
#include <shared_mutex>
#include <filesystem>
#include <fstream>
#include <cstring>
#include <sys/mman.h>
#include <fcntl.h>
#include <unistd.h>
#include <system_error>
#include <functional>
#include <map>
#include <set>

namespace banker {

constexpr size_t CHUNK_SIZE = 4 * 1024 * 1024; // 4MB
constexpr size_t NUM_CHUNKS = 256; // 256 chunks = 1GB

// 异常类，用于包装系统错误
class MemoryMapException : public std::runtime_error {
public:
    MemoryMapException(const std::string& msg, int errno_val)
        : std::runtime_error(msg + ": " + std::strerror(errno_val)), error_code(errno_val) {}
    
    int code() const { return error_code; }
    
private:
    int error_code;
};

// 管理延迟映射的内存区域
class LazyMappedMemory {
public:
    explicit LazyMappedMemory(const std::string& base_path) : base_path(base_path) {
        // 确保基础目录存在
        std::filesystem::create_directories(base_path);
        
        // 初始化映射和文件描述符
        mappings.resize(NUM_CHUNKS, nullptr);
        file_descriptors.resize(NUM_CHUNKS, -1);
    }
    
    ~LazyMappedMemory() {
        // 清理所有映射和文件描述符
        for (size_t i = 0; i < NUM_CHUNKS; ++i) {
            if (mappings[i] != nullptr) {
                munmap(mappings[i], CHUNK_SIZE);
            }
            if (file_descriptors[i] != -1) {
                close(file_descriptors[i]);
            }
        }
    }
    
    // 禁用拷贝和移动
    LazyMappedMemory(const LazyMappedMemory&) = delete;
    LazyMappedMemory& operator=(const LazyMappedMemory&) = delete;
    LazyMappedMemory(LazyMappedMemory&&) = delete;
    LazyMappedMemory& operator=(LazyMappedMemory&&) = delete;
    
    uint8_t get_byte(size_t offset) {
        if (offset >= CHUNK_SIZE * NUM_CHUNKS) {
            return 0;
        }
        
        const size_t chunk_idx = offset / CHUNK_SIZE;
        const size_t chunk_offset = offset % CHUNK_SIZE;
        
        std::shared_lock lock(mutex);
        
        // 如果映射不存在，尝试创建或返回0
        if (mappings[chunk_idx] == nullptr) {
            lock.unlock(); // 释放共享锁，获取独占锁
            std::unique_lock unique_lock(mutex);
            
            // 双重检查，防止竞态条件
            if (mappings[chunk_idx] == nullptr) {
                try {
                    ensure_mapping(chunk_idx, false);
                } catch (const MemoryMapException&) {
                    // 文件不存在，返回0
                    return 0;
                }
            }
            unique_lock.unlock();
            lock.lock(); // 重新获取共享锁
        }
        
        return static_cast<uint8_t*>(mappings[chunk_idx])[chunk_offset];
    }
    
    void set_byte(size_t offset, uint8_t value) {
        if (offset >= CHUNK_SIZE * NUM_CHUNKS) {
            return;
        }
        
        const size_t chunk_idx = offset / CHUNK_SIZE;
        const size_t chunk_offset = offset % CHUNK_SIZE;
        
        std::unique_lock lock(mutex);
        
        // 确保映射存在（如果需要则创建文件）
        if (mappings[chunk_idx] == nullptr) {
            ensure_mapping(chunk_idx, true);
        }
        
        // 写入数据
        static_cast<uint8_t*>(mappings[chunk_idx])[chunk_offset] = value;
        
        // 标记块为脏
        dirty_chunks.insert(chunk_idx);
    }
    
    // 读取64位值
    int64_t get_int64(size_t offset) {
        int64_t value = 0;
        for (int i = 0; i < 8; ++i) {
            value |= static_cast<int64_t>(get_byte(offset + i)) << (i * 8);
        }
        return value;
    }
    
    // 写入64位值
    void set_int64(size_t offset, int64_t value) {
        for (int i = 0; i < 8; ++i) {
            set_byte(offset + i, (value >> (i * 8)) & 0xFF);
        }
    }
    
    // 将所有修改刷新到磁盘
    void flush_all() {
        std::shared_lock lock(mutex);
        for (size_t i = 0; i < NUM_CHUNKS; ++i) {
            if (mappings[i] != nullptr) {
                msync(mappings[i], CHUNK_SIZE, MS_SYNC);
            }
        }
        dirty_chunks.clear();
    }
    
    // 刷新所有脏块到磁盘
    void flush_dirty_chunks() {
        std::unique_lock lock(mutex);
        for (auto chunk_idx : dirty_chunks) {
            if (mappings[chunk_idx] != nullptr) {
                msync(mappings[chunk_idx], CHUNK_SIZE, MS_SYNC);
            }
        }
        dirty_chunks.clear();
    }
    
    // 将指定块刷新到磁盘
    void flush_chunk(size_t chunk_idx) {
        if (chunk_idx >= NUM_CHUNKS) {
            return;
        }
        
        std::shared_lock lock(mutex);
        if (mappings[chunk_idx] != nullptr) {
            msync(mappings[chunk_idx], CHUNK_SIZE, MS_SYNC);
        }
        dirty_chunks.erase(chunk_idx);
    }
    
    // 卸载指定块（释放内存映射）
    void unload_chunk(size_t chunk_idx) {
        if (chunk_idx >= NUM_CHUNKS) {
            return;
        }
        
        std::unique_lock lock(mutex);
        if (mappings[chunk_idx] != nullptr) {
            munmap(mappings[chunk_idx], CHUNK_SIZE);
            mappings[chunk_idx] = nullptr;
        }
        dirty_chunks.erase(chunk_idx);
        // 注意：我们保留文件描述符以便后续快速重新映射
    }
    
private:
    void ensure_mapping(size_t chunk_idx, bool create_if_missing) {
        if (chunk_idx >= NUM_CHUNKS) {
            throw std::out_of_range("Chunk index out of range");
        }
        
        const std::string file_path = base_path + "/chunk_" + 
                                    (chunk_idx < 10 ? "00" : 
                                     chunk_idx < 100 ? "0" : "") + 
                                    std::to_string(chunk_idx) + ".bin";
        
        // 检查文件是否存在
        if (!std::filesystem::exists(file_path)) {
            if (!create_if_missing) {
                throw MemoryMapException("File does not exist", ENOENT);
            }
            
            // 创建文件并初始化为全零
            int fd = open(file_path.c_str(), O_RDWR | O_CREAT, 0644);
            if (fd == -1) {
                throw MemoryMapException("Failed to create file", errno);
            }
            
            // 设置文件大小为 CHUNK_SIZE
            if (ftruncate(fd, CHUNK_SIZE) == -1) {
                close(fd);
                throw MemoryMapException("Failed to truncate file", errno);
            }
            
            // 初始化文件内容为全零
            std::vector<uint8_t> zeros(CHUNK_SIZE, 0);
            if (write(fd, zeros.data(), zeros.size()) == -1) {
                close(fd);
                throw MemoryMapException("Failed to initialize file", errno);
            }
            
            file_descriptors[chunk_idx] = fd;
        } else if (file_descriptors[chunk_idx] == -1) {
            // 文件存在但尚未打开
            int fd = open(file_path.c_str(), O_RDWR);
            if (fd == -1) {
                throw MemoryMapException("Failed to open file", errno);
            }
            file_descriptors[chunk_idx] = fd;
        }
        
        // 创建内存映射
        void* mapping = mmap(nullptr, CHUNK_SIZE, PROT_READ | PROT_WRITE, 
                            MAP_SHARED, file_descriptors[chunk_idx], 0);
        if (mapping == MAP_FAILED) {
            throw MemoryMapException("Failed to map memory", errno);
        }
        
        mappings[chunk_idx] = mapping;
    }
    
    std::string base_path;
    std::vector<void*> mappings;
    std::vector<int> file_descriptors;
    std::set<size_t> dirty_chunks; // 跟踪哪些块被修改了
    mutable std::shared_mutex mutex;
};

// 提供线程安全版本的包装器
class ThreadSafeLazyMappedMemory {
public:
    explicit ThreadSafeLazyMappedMemory(const std::string& base_path)
        : impl(std::make_shared<LazyMappedMemory>(base_path)) {}
    
    uint8_t get_byte(size_t offset) {
        return impl->get_byte(offset);
    }
    
    void set_byte(size_t offset, uint8_t value) {
        impl->set_byte(offset, value);
    }
    
    int64_t get_int64(size_t offset) {
        return impl->get_int64(offset);
    }
    
    void set_int64(size_t offset, int64_t value) {
        impl->set_int64(offset, value);
    }
    
    void flush_all() {
        impl->flush_all();
    }
    
    void flush_dirty_chunks() {
        impl->flush_dirty_chunks();
    }
    
private:
    std::shared_ptr<LazyMappedMemory> impl;
};

} // namespace banker

// 虚拟机实现
#include <iostream>
#include <string>
#include <vector>
#include <memory>
#include <mutex>
#include <shared_mutex>
#include <filesystem>
#include <fstream>
#include <cstring>
#include <sys/mman.h>
#include <fcntl.h>
#include <unistd.h>
#include <system_error>
#include <functional>
#include <map>
#include <set>
#include <cstdint>
#include <type_traits>
#include <iomanip>

namespace banker {

// ... (banker 命名空间的代码保持不变)

} // namespace banker

// 模板化的虚拟机实现
// 虚拟机实现 - 模板化版本
template <size_t WORD_SIZE>
class VirtualMachine {
private:
    // 根据字长选择合适的数据类型
    using WordType = typename std::conditional<WORD_SIZE == 8, uint8_t,
                     typename std::conditional<WORD_SIZE == 16, uint16_t,
                     typename std::conditional<WORD_SIZE == 32, uint32_t,
                     uint64_t>::type>::type>::type;
    
    // 常量定义
    static const int MEM_LEN = 512;
    static const int CODE_SEG_BEGIN = 0;
    static const int CODE_SEG_LEN = 256;
    static const int DATA_SEG_BEGIN = 256;
    static const int DATA_SEG_LEN = 256;
    static const int COINS_REMAIN_INIT = 2618;
    
    // 全局状态
    banker::ThreadSafeLazyMappedMemory memory;
    int PC = 0;
    std::vector<WordType> REGSTACK;
    int CYCLES = 0;
    int COINS_REMAIN = COINS_REMAIN_INIT;
    
    // 指令定义
    struct Instruction {
        std::string name;
        int code;
        int args;
        std::function<void()> action;
    };
    
    std::vector<Instruction> ISA;
    std::map<std::string, std::string> ALIAS_MAP;
    
public:
    VirtualMachine(const std::string& base_path) : memory(base_path) {
        initialize_isa();
        initialize_alias_map();
    }
    
    void run() {
        // 加载测试代码
        load_test_code();
        
        // 运行机器
        while (COINS_REMAIN > 0 && PC >= 0 && PC < MEM_LEN) {
            if (!step_machine()) {
                break; // 遇到HALT指令
            }
            CYCLES++;
            
            if (PC >= MEM_LEN) {
                PC = 0;
            }
        }
        
        if (COINS_REMAIN <= 0) {
            std::cout << "NOT-ENOUGH-COINS" << std::endl;
        }
        dump_machine();
    }
    
private:
    void initialize_isa() {
        ISA = {
            {"NOP", 0, 0, [this]() { PC += 1; }},
            {"PUSH", 1, 1, [this]() { 
                WordType arg = read_code(PC + 1);
                REGSTACK.push_back(arg);
                PC += 2;
            }},
            {"POP", 2, 0, [this]() { 
                if (!REGSTACK.empty()) {
                    REGSTACK.pop_back(); 
                }
                PC += 1;
            }},
            {"ADD", 11, 0, [this]() { 
                if (REGSTACK.size() < 2) return;
                WordType op2 = REGSTACK.back(); REGSTACK.pop_back();
                WordType op1 = REGSTACK.back(); REGSTACK.pop_back();
                REGSTACK.push_back(op1 + op2);
                PC += 1;
            }},
            {"SUB", 12, 0, [this]() { 
                if (REGSTACK.size() < 2) return;
                WordType op2 = REGSTACK.back(); REGSTACK.pop_back();
                WordType op1 = REGSTACK.back(); REGSTACK.pop_back();
                REGSTACK.push_back(op1 - op2);
                PC += 1;
            }},
            {"MUL", 13, 0, [this]() { 
                if (REGSTACK.size() < 2) return;
                WordType op2 = REGSTACK.back(); REGSTACK.pop_back();
                WordType op1 = REGSTACK.back(); REGSTACK.pop_back();
                REGSTACK.push_back(op1 * op2);
                PC += 1;
            }},
            {"DIV", 14, 0, [this]() { 
                if (REGSTACK.size() < 2) return;
                WordType op2 = REGSTACK.back(); REGSTACK.pop_back();
                WordType op1 = REGSTACK.back(); REGSTACK.pop_back();
                if (op2 != 0) {
                    REGSTACK.push_back(op1 / op2);
                } else {
                    REGSTACK.push_back(0);
                }
                PC += 1;
            }},
            {"MOD", 15, 0, [this]() { 
                if (REGSTACK.size() < 2) return;
                WordType op2 = REGSTACK.back(); REGSTACK.pop_back();
                WordType op1 = REGSTACK.back(); REGSTACK.pop_back();
                if (op2 != 0) {
                    REGSTACK.push_back(op1 % op2);
                } else {
                    REGSTACK.push_back(0);
                }
                PC += 1;
            }},
            {"AND", 21, 0, [this]() { 
                if (REGSTACK.size() < 2) return;
                WordType op2 = REGSTACK.back(); REGSTACK.pop_back();
                WordType op1 = REGSTACK.back(); REGSTACK.pop_back();
                REGSTACK.push_back(op1 & op2);
                PC += 1;
            }},
            {"OR", 22, 0, [this]() { 
                if (REGSTACK.size() < 2) return;
                WordType op2 = REGSTACK.back(); REGSTACK.pop_back();
                WordType op1 = REGSTACK.back(); REGSTACK.pop_back();
                REGSTACK.push_back(op1 | op2);
                PC += 1;
            }},
            {"NOT", 23, 0, [this]() { 
                if (REGSTACK.empty()) return;
                WordType op1 = REGSTACK.back(); REGSTACK.pop_back();
                REGSTACK.push_back(~op1);
                PC += 1;
            }},
            {"EQ", 31, 0, [this]() { 
                if (REGSTACK.size() < 2) return;
                WordType op2 = REGSTACK.back(); REGSTACK.pop_back();
                WordType op1 = REGSTACK.back(); REGSTACK.pop_back();
                REGSTACK.push_back(op1 == op2 ? 1 : 0);
                PC += 1;
            }},
            {"GT", 32, 0, [this]() { 
                if (REGSTACK.size() < 2) return;
                WordType op2 = REGSTACK.back(); REGSTACK.pop_back();
                WordType op1 = REGSTACK.back(); REGSTACK.pop_back();
                REGSTACK.push_back(op1 > op2 ? 1 : 0);
                PC += 1;
            }},
            {"LT", 33, 0, [this]() { 
                if (REGSTACK.size() < 2) return;
                WordType op2 = REGSTACK.back(); REGSTACK.pop_back();
                WordType op1 = REGSTACK.back(); REGSTACK.pop_back();
                REGSTACK.push_back(op1 < op2 ? 1 : 0);
                PC += 1;
            }},
            {"LOAD", 41, 1, [this]() { 
                int addr = read_code(PC + 1);
                REGSTACK.push_back(get_data(addr));
                PC += 2;
            }},
            {"STORE", 42, 1, [this]() { 
                int addr = read_code(PC + 1);
                if (!REGSTACK.empty()) {
                    set_data(addr, REGSTACK.back());
                    REGSTACK.pop_back();
                }
                PC += 2;
            }},
            {"LOAD_INDIRECT", 43, 0, [this]() { 
                if (REGSTACK.empty()) return;
                int addr = REGSTACK.back(); REGSTACK.pop_back();
                REGSTACK.push_back(get_data(addr));
                PC += 1;
            }},
            {"STORE_INDIRECT", 44, 0, [this]() { 
                if (REGSTACK.size() < 2) return;
                int addr = REGSTACK.back(); REGSTACK.pop_back();
                WordType val = REGSTACK.back(); REGSTACK.pop_back();
                set_data(addr, val);
                PC += 1;
            }},
            {"JUMP", 51, 1, [this]() { 
                PC = read_code(PC + 1);
            }},
            {"JUMPIF", 52, 1, [this]() { 
                if (REGSTACK.empty()) {
                    PC += 2;
                } else {
                    WordType condition = REGSTACK.back(); REGSTACK.pop_back();
                    if (condition == 0) {
                        PC += 2;
                    } else {
                        PC = read_code(PC + 1);
                    }
                }
            }},
            {"PRINT", 61, 0, [this]() { 
                if (!REGSTACK.empty()) {
                    std::cout << static_cast<uint64_t>(REGSTACK.back()) << std::endl;
                    REGSTACK.pop_back();
                }
                PC += 1;
            }},
            {"HALT", 255, 0, [this]() {}}
        };
    }
    
    void initialize_alias_map() {
        ALIAS_MAP = {
            {"+", "ADD"}, {"-", "SUB"}, {"*", "MUL"}, {"/", "DIV"}, {"%", "MOD"},
            {"=", "EQ"}, {">", "GT"}, {"<", "LT"},
            {"&", "AND"}, {"|", "OR"}, {"~", "NOT"},
            {"JMP", "JUMP"}, {"HLT", "HALT"}
        };
    }
    
    // 基本设施
    WordType read_code(int addr) {
        // 根据字长计算字节偏移量
        size_t byte_offset = (CODE_SEG_BEGIN + addr) * (WORD_SIZE / 8);
        
        if constexpr (WORD_SIZE == 8) {
            return memory.get_byte(byte_offset);
        } else if constexpr (WORD_SIZE == 16) {
            // 读取两个字节并组合成16位值
            uint16_t low = memory.get_byte(byte_offset);
            uint16_t high = memory.get_byte(byte_offset + 1);
            return (high << 8) | low;
        } else if constexpr (WORD_SIZE == 32) {
            // 读取四个字节并组合成32位值
            uint32_t value = 0;
            for (int i = 0; i < 4; ++i) {
                value |= static_cast<uint32_t>(memory.get_byte(byte_offset + i)) << (i * 8);
            }
            return value;
        } else { // 64位
            return memory.get_int64(byte_offset);
        }
    }
    
    WordType get_data(int addr) {
        // 根据字长计算字节偏移量
        size_t byte_offset = (DATA_SEG_BEGIN + addr) * (WORD_SIZE / 8);
        
        if constexpr (WORD_SIZE == 8) {
            return memory.get_byte(byte_offset);
        } else if constexpr (WORD_SIZE == 16) {
            // 读取两个字节并组合成16位值
            uint16_t low = memory.get_byte(byte_offset);
            uint16_t high = memory.get_byte(byte_offset + 1);
            return (high << 8) | low;
        } else if constexpr (WORD_SIZE == 32) {
            // 读取四个字节并组合成32位值
            uint32_t value = 0;
            for (int i = 0; i < 4; ++i) {
                value |= static_cast<uint32_t>(memory.get_byte(byte_offset + i)) << (i * 8);
            }
            return value;
        } else { // 64位
            return memory.get_int64(byte_offset);
        }
    }
    
    void set_data(int addr, WordType val) {
        // 根据字长计算字节偏移量
        size_t byte_offset = (DATA_SEG_BEGIN + addr) * (WORD_SIZE / 8);
        
        if constexpr (WORD_SIZE == 8) {
            memory.set_byte(byte_offset, val);
        } else if constexpr (WORD_SIZE == 16) {
            // 将16位值分解为两个字节存储
            memory.set_byte(byte_offset, val & 0xFF);
            memory.set_byte(byte_offset + 1, (val >> 8) & 0xFF);
        } else if constexpr (WORD_SIZE == 32) {
            // 将32位值分解为四个字节存储
            for (int i = 0; i < 4; ++i) {
                memory.set_byte(byte_offset + i, (val >> (i * 8)) & 0xFF);
            }
        } else { // 64位
            memory.set_int64(byte_offset, val);
        }
    }
    
    WordType get_arg() {
        return read_code(PC + 1);
    }
    
    WordType get_instr() {
        return read_code(PC);
    }
    
    // 加载测试代码
    void load_test_code() {
        std::vector<std::string> test_code = {
            "PUSH", "100",
            "STORE", "100",
            "LOOP:",
            "LOAD", "100",
            "PUSH", "1",
            "SUB",
            "STORE", "100",
            "LOAD", "100",
            "LOAD", "100",
            "STORE_INDIRECT",
            "LOAD", "100",
            "PUSH", "0",
            "EQ",
            "JUMPIF", "PRIME_LEFT",
            "JUMP", "LOOP",
            "PRIME_LEFT:",
            "PUSH", "2",
            "STORE", "1",
            "P_LOOP:",
            "LOAD", "1",
            "LOAD", "1",
            "MUL",
            "PUSH", "100",
            "GT",
            "JUMPIF", "HALT",
            "LOAD", "1",
            "LOAD_INDIRECT",
            "PUSH", "0",
            "EQ",
            "JUMPIF", "SKIP_MARK",
            "JUMP", "MARK_MULTIPLES",
            "MARK_MULTIPLES:",
            "LOAD", "1",
            "LOAD", "1",
            "MUL",
            "STORE", "0",
            "I_LOOP:",
            "LOAD", "0",
            "PUSH", "100",
            "LT",
            "JUMPIF", "I_CONTINUE",
            "JUMP", "SKIP_MARK",
            "I_CONTINUE:",
            "PUSH", "0",
            "LOAD", "0",
            "STORE_INDIRECT",
            "LOAD", "0",
            "LOAD", "1",
            "ADD",
            "STORE", "0",
            "JUMP", "I_LOOP",
            "SKIP_MARK:",
            "LOAD", "1",
            "PUSH", "1",
            "ADD",
            "STORE", "1",
            "JUMP", "P_LOOP",
            "HALT:",
            "HALT"
        };
        
        // 汇编代码并加载到内存
        auto bytecode = assemble(test_code);
        for (size_t i = 0; i < bytecode.size() && i < CODE_SEG_LEN; i++) {
            // 根据字长计算字节偏移量
            size_t byte_offset = (CODE_SEG_BEGIN + i) * (WORD_SIZE / 8);
            
            if constexpr (WORD_SIZE == 8) {
                memory.set_byte(byte_offset, bytecode[i]);
            } else if constexpr (WORD_SIZE == 16) {
                // 将16位值分解为两个字节存储
                memory.set_byte(byte_offset, bytecode[i] & 0xFF);
                memory.set_byte(byte_offset + 1, (bytecode[i] >> 8) & 0xFF);
            } else if constexpr (WORD_SIZE == 32) {
                // 将32位值分解为四个字节存储
                for (int j = 0; j < 4; ++j) {
                    memory.set_byte(byte_offset + j, (bytecode[i] >> (j * 8)) & 0xFF);
                }
            } else { // 64位
                memory.set_int64(byte_offset, bytecode[i]);
            }
        }
    }
    
    // 简单的汇编器
    std::vector<WordType> assemble(const std::vector<std::string>& tokens) {
        // 简化的汇编器实现
        std::vector<WordType> result;
        std::map<std::string, int> labels;
        
        // 第一遍：收集标签
        int addr = 0;
        for (size_t i = 0; i < tokens.size(); i++) {
            const std::string& token = tokens[i];
            if (token.back() == ':') {
                labels[token.substr(0, token.size() - 1)] = addr;
            } else {
                // 查找指令或别名
                std::string actual_name = token;
                if (ALIAS_MAP.find(token) != ALIAS_MAP.end()) {
                    actual_name = ALIAS_MAP[token];
                }
                
                // 查找指令
                for (const auto& instr : ISA) {
                    if (instr.name == actual_name) {
                        addr++;
                        if (instr.args > 0) {
                            i++;
                            addr++;
                        }
                        break;
                    }
                }
            }
        }
        
        // 第二遍：生成代码
        for (size_t i = 0; i < tokens.size(); i++) {
            const std::string& token = tokens[i];
            if (token.back() == ':') {
                continue; // 跳过标签定义
            }
            
            // 查找指令或别名
            std::string actual_name = token;
            if (ALIAS_MAP.find(token) != ALIAS_MAP.end()) {
                actual_name = ALIAS_MAP[token];
            }
            
            // 查找指令
            for (const auto& instr : ISA) {
                if (instr.name == actual_name) {
                    result.push_back(instr.code);
                    
                    if (instr.args > 0) {
                        i++;
                        if (i < tokens.size()) {
                            const std::string& arg = tokens[i];
                            if (labels.find(arg) != labels.end()) {
                                result.push_back(labels[arg]);
                            } else {
                                try {
                                    result.push_back(std::stoi(arg));
                                } catch (...) {
                                    result.push_back(0);
                                }
                            }
                        } else {
                            result.push_back(0);
                        }
                    }
                    break;
                }
            }
        }
        
        return result;
    }
    
    // 调试函数
    void dump_machine() {
        std::cout << "((CODE-SEG-BEGIN " << CODE_SEG_BEGIN << ")" << std::endl;
        std::cout << " (CODE-SEG-LEN " << CODE_SEG_LEN << ")" << std::endl;
        std::cout << " (DATA-SEG-BEGIN " << DATA_SEG_BEGIN << ")" << std::endl;
        std::cout << " (DATA-SEG-LEN " << DATA_SEG_LEN << ")" << std::endl;
        std::cout << " (PC " << PC << ")" << std::endl;
        std::cout << " (REGSTACK (";
        for (size_t i = 0; i < REGSTACK.size(); i++) {
            if (i > 0) std::cout << " ";
            std::cout << static_cast<uint64_t>(REGSTACK[i]);
        }
        std::cout << "))" << std::endl;
        std::cout << " (COINS-REMAIN " << COINS_REMAIN << ")" << std::endl;
        std::cout << " (CYCLES " << CYCLES << "))" << std::endl;
    }
    
    void debug_print() {
        std::map<int, std::string> dasm_map;
        for (const auto& instr : ISA) {
            dasm_map[instr.code] = instr.name;
        }
        
        WordType instr_code = get_instr();
        std::string instr_name = dasm_map.count(instr_code) ? dasm_map[instr_code] : "UNKNOWN";
        
        std::cout << "(CYCLES: " << CYCLES << " REGSTACK: (";
        for (size_t i = 0; i < REGSTACK.size(); i++) {
            if (i > 0) std::cout << " ";
            std::cout << static_cast<uint64_t>(REGSTACK[i]);
        }
        std::cout << ") instr: " << instr_name;
        
        for (const auto& instr : ISA) {
            if (instr.code == instr_code && instr.args > 0) {
                std::cout << " " << static_cast<uint64_t>(get_arg());
                break;
            }
        }
        std::cout << ")" << std::endl;
    }
    
    bool step_machine() {
        debug_print();
        
        WordType instr_code = get_instr();
        
        // 查找并执行指令
        for (const auto& instr : ISA) {
            if (instr.code == instr_code) {
                // 执行指令
                instr.action();
                
                // 确保指令的原子性：刷新所有脏块到磁盘
                memory.flush_dirty_chunks();
                
                COINS_REMAIN--;
                return instr_code != 255; // 如果不是HALT指令，返回true
            }
        }
        
        // 未知指令，跳过
        PC += 1;
        COINS_REMAIN--;
        return true;
    }
};

// 辅助函数，用于创建特定字长的虚拟机
template <uint8_t n>
void run_virtual_machine(const std::string& base_path) {
    VirtualMachine<n> vm(base_path);
    vm.run();
}

int main() {
    const std::string base_path = "./vm_memory";
    try {
        
        
        // 选择要运行的虚拟机类型
        std::cout << "Select virtual machine type:" << std::endl;
        std::cout << "1. 8-bit" << std::endl;
        std::cout << "2. 16-bit" << std::endl;
        std::cout << "3. 32-bit" << std::endl;
        std::cout << "4. 64-bit" << std::endl;
        std::cout << "Enter your choice (1-4): ";
        
        int choice;
        std::cin >> choice;
        
        switch (choice) {
            case 1:
                run_virtual_machine<8>(base_path);
                break;
            case 2:
                run_virtual_machine<16>(base_path);
                break;
            case 3:
                run_virtual_machine<32>(base_path);
                break;
            case 4:
                run_virtual_machine<64>(base_path);
                break;
            default:
                std::cout << "Invalid choice. Running 64-bit VM by default." << std::endl;
                run_virtual_machine<64>(base_path);
                break;
        }
        
    } catch (const std::exception& e) {
        std::cerr << "Error: " << e.what() << std::endl;
        return 1;
    }
    system((std::string("hexdump -C -n 4096 ") + base_path + std::string("/chunk_000.bin")).c_str());
    
    return 0;
};
